package com.li.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.CharArrayReader;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * 按流是否直接与特定的地方（如磁盘、内存、设备等）相连，分为节点流和处理流两种
 * 节点流：可以从或者向一个特定的地方（节点）读写数据，如
 * FileReader 文件字符输入流，对文件进行相应的读写
 * StringReader 字符串输入流，对字符串进行相应的读写操作
 * CharArrayReader 对字符数组进行相应的读写操作
 * PipeReader 对管道进行相应的读写操作
 * 
 * 处理流：是对一个已存在的流的连接和封装，通过所封装的流的功能调用实现数据读写如：
 * BufferedReader 对字符流进行缓存操作，大大提高数据读写的效率
 * InputStreamReader 将字节流转换为字符流
 * PrintWriter 字符打印流
 * 
 * @author Administrator
 *
 */
public class ReaderDemo {
	public static void main(String[] args) throws Exception {
		//testFileReader();
		//testFileWriter();
		//testStringReader();
		//testStringWriter();
		//testBufferedReader();
		//testBufferedWriter();
		//testCharArrayReader();
		//testCharArrayWriter();
		//testInputStreamReader();
		//testOutputStreamWriter();
		testPrintWriter();
	}

	/**
	 * 对文件进行读写操作，主要是针对字符的操作
	 * @throws IOException
	 */
	public static void testFileReader() throws IOException{
		FileReader r=new FileReader("src/main/java/com/li/io/test.txt");
		int data;
		while((data=r.read())!=-1){
			System.out.print((char)data);
		}
		r.close();
	}

	public static void testFileWriter() throws Exception{
		FileReader r=new FileReader("src/main/java/com/li/io/test.txt");
		FileWriter rw=new FileWriter("src/main/java/com/li/io/test2.txt");
		char[] data=new char[1024];
		while(r.read(data)!=-1){
			System.out.println(data);
			rw.write(data,0,data.length);
		}
		rw.flush();
		rw.close();
		r.close();
	}
	/**
	 * 对字符串进行相应的读写操作，一般情况下用String，只有在指定类型必须为
	 * StringReader时一般才能派上用场
	 * @throws IOException
	 */
	public static void testStringReader() throws IOException{
		StringReader sr=new StringReader("呵呵哒");
		char[] data=new char[1024];
		int len=0;
		while((len=sr.read(data))!=-1){
			System.out.print(data);
		}
		sr.close();
	}

	public static void testStringWriter() throws Exception{
		StringReader sr=new StringReader("呵呵哒");
		StringWriter sw=new StringWriter();
		char[] data=new char[1024];
		int len=0;
		while((len=sr.read(data))!=-1){
			sw.write(data, 0, len);
			System.out.print(sw);
		}
		sw.flush();
		sw.close();
		sr.close();
	}
	
	/**
	 * 字符缓冲流，对字符流进行相应的封装，提供自己的一些功能给字符流
	 * 缓冲流有一个固定大下的缓冲区，每次数据读写都先读取到缓冲区中，这样能够大大滴提高
	 * 读写效率，减少磁盘的开销
	 * @throws Exception
	 */
	public static void testBufferedReader() throws Exception{
		BufferedReader fr=new BufferedReader(new FileReader("src/main/java/com/li/io/test.txt"));
		char[] data=new char[1024];
		int len=0;
		while((len=fr.read(data))!=-1){
			System.out.print(data);
		}
		fr.close();
	}
	
	public static void testBufferedWriter() throws Exception{
		BufferedReader fr=new BufferedReader(new StringReader("呵呵哒"));
		BufferedWriter bw=new BufferedWriter(new FileWriter("src/main/java/com/li/io/test2.txt"));
		char[] data=new char[1024];
		int len=0;
		while((len=fr.read(data))!=-1){
			bw.write(data);
		}
		bw.flush();
		bw.close();
		fr.close();
	}
	/**
	 * 字符数组输入输出流，对内存中的字符数组进行相应的读写操作
	 * 一般用作中间的流
	 * @throws Exception
	 */
	public static void testCharArrayReader() throws Exception{
		char[] data={'a','b','c','d','e'};
		CharArrayReader cr=new CharArrayReader(data);
		char[] temp=new char[1024];
		int len=0;
		while((len=cr.read(temp))!=-1){
			System.out.print(temp);
		}
		cr.close();
	}
	
	public static void testCharArrayWriter() throws Exception{
		char[] data={'a','b','c','d','e'};
		CharArrayReader cr=new CharArrayReader(data);
		CharArrayWriter cw=new CharArrayWriter();
		char[] temp=new char[1024];
		int len=0;
		while((len=cr.read(temp))!=-1){
			cw.write(temp);
		}
		System.out.println(cw);
		cw.flush();
		cw.close();
		cr.close();
		}
	/**
	 * 将字节流转换为字符流
	 * 这样能够更好地支持字符数据的读写和保证正确性，因为
	 * java是采用unicode编码，一个字符占用两个字节，字节流来处理字符会出现一定的乱码问题	
	 * @throws Exception
	 */
	public static void testInputStreamReader() throws Exception{
		InputStream is=new FileInputStream(new File("src/main/java/com/li/io/test.txt"));
		Reader r=new InputStreamReader(is);
		char[] data=new char[1024];
		int len=0;
		while((len=r.read(data))!=-1){
			System.out.print(data);
		}
		r.close();
		is.close();
	}
	
	public static void testOutputStreamWriter() throws Exception{
		OutputStream os=new FileOutputStream("src/main/java/com/li/io/test2.txt");
		OutputStreamWriter ow=new OutputStreamWriter(os);
		ow.write("借金额大");
		ow.close();
		os.close();
	}
	/**
	 * 字符打印流，对字符进行打印操作，打印流封装字符流，提供了很多好用的方法和功能
	 * @throws Exception
	 */
	public static void testPrintWriter() throws Exception{
		OutputStream os=new FileOutputStream("src/main/java/com/li/io/test2.txt");
		PrintWriter pw=new PrintWriter(os);
		pw.println("aaaaaa");
		pw.close();
		os.close();
	}
}
